#include "Malloc.h"
#include <vector>
#include <stdlib.h>
#include <thread>
void TestMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> timealloc(0);
    std::atomic<size_t> timefree(0);

    for (size_t k = 0; k < nworks; ++k) {
        vthread[k] = std::thread([&]() {
            std::vector<void *> v;
            v.reserve(ntimes);

            for (size_t j = 0; j < rounds; ++j) {
                size_t begin1 = clock();
                for (size_t i = 0; i < ntimes; i++) {
                    void *p = malloc(1024*(j+1));
                    v.push_back(p);
                }
                size_t end1 = clock();
                timealloc += end1 - begin1;
                begin1 = clock();
                for (auto p : v) {
                    free(p);
                }
                end1 = clock();
                timefree += end1 - begin1;
                v.clear();
            }
        });
    }

    for (auto &t : vthread) {
        t.join();
    }
    printf("malloc: %lu threads %lu rounds %lu times %lu clocks\n", nworks, rounds, ntimes, timealloc.load());
    printf("free: %lu threads %lu rounds %lu times %lu clocks\n", nworks, rounds, ntimes, timefree.load());
    printf("sum: %lu threads %lu rounds %lu times %lu clocks\n", nworks, rounds, ntimes, timealloc.load() + timefree.load());
}

// 单轮次申请释放次数 线程数 轮次
void TestConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> timealloc(0);
    std::atomic<size_t> timefree(0);

    for (size_t k = 0; k < nworks; ++k) {
        vthread[k] = std::thread([&]() {
            std::vector<void *> v;

            for (size_t j = 0; j < rounds; ++j) {
                size_t begin1 = clock();
                for (size_t i = 0; i < ntimes; i++) {
                    void *p = ConcurrentMalloc(1024*(j+1));
                    v.push_back(p);
                }
                size_t end1 = clock();
                timealloc += end1 - begin1;
                begin1 = clock();
                for (auto p : v) {
                    ConcurrentFree(p);
                }
                end1 = clock();
                timefree += end1 - begin1;
                v.clear();
            }
        });
    }

    for (auto &t : vthread) {
        t.join();
    }
    printf("concurrent malloc: %lu threads %lu rounds %lu times %lu clocks\n", nworks, rounds, ntimes, timealloc.load());
    printf("concurrent free: %lu threads %lu rounds %lu times %lu clocks\n", nworks, rounds, ntimes, timefree.load());
    printf("concurrent sum: %lu threads %lu rounds %lu times %lu clocks\n", nworks, rounds, ntimes, timealloc.load() + timefree.load());
}

int main()
{
    int times = 10000;
    int rounds = 10;
    int threads = 4;
    cout << "==========================================================" << endl;
    TestConcurrentMalloc(times, threads, rounds);
    cout << "==========================================================" << endl;
    TestMalloc(times, threads, rounds);
    return 0;
}